#include "print.h"

// 实现 write 方法（支持写入缓冲区）
size_t Print::write(const uint8_t *buffer, size_t size) {
    size_t n = 0;
    for (size_t i = 0; i < size; i++) {
        n += write(buffer[i]);
    }
    return n;
}

// 核心打印方法实现
size_t Print::print(const std::string &s) {
    return write(reinterpret_cast<const uint8_t*>(s.c_str()), s.size());
}

size_t Print::print(char c) {
    return write(static_cast<uint8_t>(c));
}

size_t Print::print(int16_t num, int16_t base) {
    return print(static_cast<int32_t>(num), base);
}

size_t Print::print(uint16_t num, int16_t base) {
    return print(static_cast<uint32_t>(num), base);
}

size_t Print::print(int32_t num, int16_t base) {
    if (base == 0) return write(static_cast<uint8_t>(num));
    if (num < 0 && base == 10) {
        return print('-') + printNumber(-num, base);
    }
    return printNumber(num, base);
}

size_t Print::print(uint32_t num, int16_t base) {
    if (base == 0) return write(static_cast<uint8_t>(num));
    return printNumber(num, base);
}

size_t Print::print(double num, int16_t precision) {
    return printFloat(num, precision);
}

// 换行打印实现
size_t Print::println(const std::string &s) {
    return print(s) + println();
}

size_t Print::println(char c) {
    return print(c) + println();
}

size_t Print::println(int16_t num, int16_t base) {
    return print(num, base) + println();
}

size_t Print::println(uint16_t num, int16_t base) {
    return print(num, base) + println();
}

size_t Print::println(int32_t num, int16_t base) {
    return print(num, base) + println();
}

size_t Print::println(uint32_t num, int16_t base) {
    return print(num, base) + println();
}

size_t Print::println(double num, int16_t precision) {
    return print(num, precision) + println();
}

size_t Print::println() {
    return write('\r') + write('\n');
}

// 内部工具函数
size_t Print::printNumber(uint32_t num, uint8_t base) {
    char buf[10] = {0};
    char *str = &buf[sizeof(buf)-1];
    if (num == 0) {
        return print('0');
    }
    while (num > 0) {
        char c = num % base;
        *--str = (c < 10) ? c + '0' : c + 'A' - 10;
        num /= base;
    }
    return print(std::string(str));
}

size_t Print::printFloat(double num, uint8_t precision) {
    size_t n = 0;
    if (num < 0) {
        n += print('-');
        num = -num;
    }
    double rounding = 0.5;
    for (uint8_t i = 0; i < precision; ++i) {
        rounding /= 10.0;
    }
    num += rounding;
    uint32_t integer = static_cast<uint32_t>(num);
    n += print(integer);
    if (precision > 0) {
        n += print('.');
        double fraction = num - integer;
        for (uint8_t i = 0; i < precision; i++) {
            fraction *= 10.0;
            uint16_t digit = static_cast<uint16_t>(fraction);
            n += print(digit);
            fraction -= digit;
        }
    }
    return n;
}
